﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Casamiel.API.Application;
using Casamiel.API.Application.Commands;
using Casamiel.API.Application.Models;
using Casamiel.API.Application.Models.ICModels;

using Casamiel.API.Application.Models.Store;
using Casamiel.API.Application.Models.V2;
using Casamiel.API.Application.Services;
using Casamiel.API.Infrastructure;
using Casamiel.API.Infrastructure.Filters;
using Casamiel.Application;
using Casamiel.Application.Commands;
using Casamiel.Application.Commands.Waimai;
using Casamiel.Application.Commands.Wechat;
using Casamiel.Common;
using Casamiel.Common.Extensions;
using Casamiel.Domain;
using Casamiel.Domain.Entity;
using Casamiel.Domain.Request;
using Casamiel.Domain.Request.CakeMall;
using Casamiel.Domain.Request.Waimai;
using Casamiel.Domain.Response;

using Casamiel.Domain.Response.Waimai;
using Enyim.Caching;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Constant = Casamiel.Common.Constant;

namespace Casamiel.API.Controllers.V1.WaiMai
{
    /// <summary>
    /// waimai产品
    /// </summary>
    [ApiVersion("1.0")]
    [Route("api/v{api-version:apiVersion}/WaiMai/[controller]")]
    [ApiController]
    [EnableCors("any")]
    [Authorize]

    public class OrderController : BaseController
    {
        private readonly IMediator _mediator;
        private readonly NLog.ILogger logger = NLog.LogManager.GetLogger("OrderService");
        private readonly IIcApiService _icApiService;
        private readonly INetICService _netICService;
        private readonly IStoreService _storeService;
        private readonly ICasaMielSession _session;
        private readonly IPaymentService _paymentService;
        private readonly IMemberCardService _memberCardService;
        private readonly IUserLogService _userLog;
        private readonly IMemcachedClient _memcachedClient;
        private readonly string _memcachedPrex;
        private readonly INoticeService _notice;
        private readonly IOrderService _order;
        private readonly IRefundService _refundService;
        private readonly string _apiname;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="notice"></param>
        /// <param name="mediator"></param>
        /// <param name="iicApiService"></param>
        /// <param name="storeService"></param>
        /// <param name="casaMielSession"></param>
        /// <param name="paymentService"></param>
        /// <param name="memberCardService"></param>
        /// <param name="userLogService"></param>
        /// <param name="memcachedClient"></param>
        /// <param name="optionsSnapshot"></param>
        /// <param name="order"></param>
        /// <param name="refundService"></param>
        /// <param name="netICService"></param>
        public OrderController(INoticeService notice, IMediator mediator, IIcApiService iicApiService, IStoreService storeService, ICasaMielSession casaMielSession, IPaymentService paymentService,
        IMemberCardService memberCardService, IUserLogService userLogService, IMemcachedClient memcachedClient,
        IOptionsSnapshot<CasamielSettings> optionsSnapshot, IOrderService order, IRefundService refundService,
        INetICService netICService)
        {
            if (optionsSnapshot == null) {
                throw new ArgumentNullException(nameof(optionsSnapshot));
            }
            _netICService = netICService;
            _mediator = mediator;
            _icApiService = iicApiService;
            _storeService = storeService;
            _session = casaMielSession;
            _paymentService = paymentService;
            _memberCardService = memberCardService;
            _userLog = userLogService;
            _memcachedClient = memcachedClient;
            _memcachedPrex = optionsSnapshot.Value.MemcachedPre;
            _apiname = optionsSnapshot.Value.ApiName;
            _notice = notice;
            _order = order;
            _refundService = refundService;
        }
        /// <summary>
        /// 外卖配送费规则
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<BaseResult<TakeOutConfigRsp>> GetFreightRule()
        {
            var cmd = new GetFreightRuleCommand();
            var rsp = await _mediator.Send(cmd).ConfigureAwait(false);
            return rsp;
        }


        /// <summary>
        /// 外卖配送费
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        //[TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<BaseResult<TakeOutGetFreightMoneyRsp>> CalculateFreightFee([FromBody] CalculateFreightFeeReq req, [FromHeader(Name = "u-token")] string token)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }
            var mobile = MemberHelper.GetMobile(token);
            Console.WriteLine(mobile);
            var cmd = new CalculateFreightFeeCommand { OrderMoney = req.OrderMoney };
            var rsp = await _mediator.Send(cmd).ConfigureAwait(false);
            return rsp;
        }


        /// <summary>
        ///我的会员券
        /// </summary>
        /// <param name="request"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<BaseResult<List<TicketItem>>> GetMyTickets(GetMyCouponsRequest request, [FromHeader(Name = "u-token")] string token)
        {
            if (request is null) {
                throw new ArgumentNullException(nameof(request));
            }

            var mobile = MemberHelper.GetMobile(token);
            //var glist = new List<Domain.Request.Waimai.TakeOutOrderGoods>();
            //foreach (var item in request.GoodsList) {
            //    glist.Add(new Domain.Request.Waimai.TakeOutOrderGoods {
            //        GoodsBaseId = item.GoodsBaseId,
            //        GoodsQuantity = item.GoodsQuantity,
            //        GoodsRelationId = item.GoodsRelationId,
            //        Price = item.Price

            //    });
            //}
            var cmd = new GetTicketsStatusByOrderCommand(request.GoodsList, request.StoreId, mobile, true,LoginInfo.Item3);
            return await _mediator.Send(cmd).ConfigureAwait(false);

        }

        /// <summary>
        ///我的代金券列表
        /// </summary>
        /// <param name="request"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<BaseResult<List<MemberCouponReponse>>> GetMyCoupons(GetMyCouponsRequest request, [FromHeader(Name = "u-token")] string token)
        {
            if (request is null) {
                throw new ArgumentNullException(nameof(request));
            }


            var mobile = MemberHelper.GetMobile(token);
            var cmd = new GetMyUsableCouponsCommand(request.GoodsList, request.StoreId, mobile, false,LoginInfo.Item3);
            return await _mediator.Send(cmd).ConfigureAwait(false);
        }



        /// <summary>
        /// 订单预览
        /// </summary>
        /// <param name="request"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<BaseResult<OrderPreviewReponse>> OrderPreview(Domain.Request.Waimai.OrderPreviewRequest request, [FromHeader(Name = "u-token")] string token)
        {
            if (request == null) {
                throw new ArgumentNullException(nameof(request));
            }

            var Loginfo = this.LoginInfo;
            var mobile = MemberHelper.GetMobile(token);

            var cmd = new OrderPreviewCommand(request, mobile, LoginInfo.Item3);

            var rsp = await _mediator.Send(cmd).ConfigureAwait(false);
            return rsp;
        }



        /// <summary>
        /// 创建订单
        /// </summary>
        /// <param name="req"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        [HttpPost]
        [Route("[action]")]
        public async Task<BaseResult<PaymentRsp>> CreateOrder([FromBody] TakeOutOrderCreateReq req, [FromHeader(Name = "u-token")] string token)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }

            var loginInfo = this.LoginInfo;
            var mobile = MemberHelper.GetMobile(token);

            var cmd = new CreateOrderCommand(loginInfo.Item3) {
                PayCardNO = req.PayCardNO,
                Paymethod = req.Paymethod,
                ConsigneeId = req.ConsigneeId,
                ContactName = req.ContactName,
                TakeTime = req.TakeTime,
                GoodsList = req.GoodsList,
                Mobile = mobile,
                OrderType = req.OrderType,
                FreightMoney = req.FreightMoney,
                StoreId = req.StoreId,
                Id = req.Id,
                DiscountList = new List<OrderDiscountReq>(),
                ContactPhone = req.ContactPhone,
                InvoiceId = req.InvoiceId,
                Remark = req.Remark
            };
            if (req.DiscountCouponId > 0) {
                cmd.DiscountList.Add(new OrderDiscountReq {
                    CardNo = req.CardNo, DiscountCouponId = req.DiscountCouponId,
                    DiscountCouponType = 1,
                    DiscountCouponMoney = req.DiscountCouponMoney,
                    DiscountCouponName = req.DiscountCouponName
                });
            }

            var result = await _mediator.Send(cmd).ConfigureAwait(false);
            logger.Trace($"req:{JsonConvert.SerializeObject(cmd)},{JsonConvert.SerializeObject(result)}");
            if (result.Code == 0 && result.Content.Payed != true) {
                logger.Trace($"{JsonConvert.SerializeObject(result.Content)}");
                var array = result.Content.Paymentrequest.Split(',');
                var p_tradeno = $"C{DateTime.Now.ToString("yyMMddHHmmssfff", CultureInfo.CurrentCulture)}";
                var payment = new PaymentRecord {
                    ShopName = "",
                    OperationMethod = (int)OperationMethod.Waimai,
                    TradeNo = p_tradeno,
                    Amount = array[0].ToDouble(0),
                    PayMethod = req.Paymethod,
                    BillNO = result.Content.OrderCode,
                    IcTradeNO = array[1].ToString(CultureInfo.CurrentCulture),
                    State = 0,
                    OperationState = 0,
                    CreateTime = DateTime.Now,
                    Mobile = mobile
                };

                string shopno;
                var shopinfo = await _storeService.GetByStoreIdAsync<ICasaMielSession>(req.StoreId).ConfigureAwait(false);
                if (shopinfo != null) {
                    payment.ShopName = shopinfo.StoreName;
                    payment.ShopId = shopinfo.RelationId;
                }


                var cachekey = string.Format(CultureInfo.CurrentCulture, Constant.SHOPNO, _memcachedPrex, payment.ShopId);
                shopno = await _memcachedClient.GetValueAsync<string>(cachekey).ConfigureAwait(false);
                if (string.IsNullOrEmpty(shopno)) {
                    var basedata = await _icApiService.BasedataQuery(new BasedataqueryReq { Datatype = 3, Datavalue = $"{payment.ShopId.Value}" }).ConfigureAwait(false);
                    if (basedata.code == 0) {
                        var d = JsonConvert.DeserializeObject<JArray>(basedata.content);
                        if (d.Count > 0) {
                            shopno = d[0]["no"].ToString();
                            await _memcachedClient.AddAsync(cachekey, shopno, 72000).ConfigureAwait(false);
                        }
                    }
                }
                payment.ShopNO = shopno;

                var command = new Application.Commands.CreatePaymentRequestCommand(payment, req.Id, PaymentScenario.Waimai);
                var result1 = await _mediator.Send(command).ConfigureAwait(false);

                var pay = new PaymentRsp {
                    OrderCode = result1.Ordercode,
                    Payed = result1.Payed,
                    Paymentrequest = result1.Paymentrequest,
                    PayMethod = result1.PayMethod.ToInt32(0)
                };
                return new BaseResult<PaymentRsp>(pay, 0, "");
            }
            if (result.Code == 0 && result.Content.Payed) {
                var cmd3 = new OrderCreateMemberCouponCommand { ActivityId = 6, OrderCode = result.Content.OrderCode };
                var rsp = await _mediator.Send(cmd3).ConfigureAwait(false);
                logger.Trace($"OrderCreateMemberCouponCommand:{ result.Content.OrderCode},{JsonConvert.SerializeObject(rsp)}");
                //var SendOrderPaySuccessCmd = new Casamiel.Application.Commands.SendOrderPaySuccessTemplateMessageCommand { OrderCode = result.content.OrderCode };
                //await _mediator.Send(SendOrderPaySuccessCmd);
            }


            return result;

        }

        /// <summary>
        /// Payment the specified data and token.
        /// </summary>
        /// <returns>The payment.</returns>
        /// <param name="data">Data.</param>
        /// <param name="token">Token.</param>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<BaseResult<PaymentRsp>> Payment([FromBody] OrderPaymentRequest data, [FromHeader(Name = "u-token")]string token)
        {
            if (data == null) {
                throw new ArgumentNullException(nameof(data));
            }

            var mobile = MemberHelper.GetMobile(token);
            var order = await _order.GetByOrderCodeAsync<ICasaMielSession>(data.OrderCode, mobile).ConfigureAwait(false);
            if (order == null) {
                return new BaseResult<PaymentRsp>(null, -23, "订单不存在");
            }
            var Storeinfo = await _storeService.GetByStoreIdAsync<ICasaMielSession>(order.StoreId).ConfigureAwait(false);
            if (Storeinfo == null) {
                return new BaseResult<PaymentRsp>(null, -23, "订单不存在");
            }
            if (order.OrderStatus != (int)OrderStatus.Create) {
                return new BaseResult<PaymentRsp>(null, -24, "订单状态不是待支付");
            }

            var payRsp = new PaymentRsp {
                OrderCode = order.OrderCode,
                PayMethod = data.PayMethod

            };
            if (order.OrderType == 1) {
                var orderTake = await _storeService.GetOrdeTakeByOrderCodeAsync<ICasaMielSession>(order.OrderBaseId).ConfigureAwait(false);
                if (orderTake == null) {
                    return new BaseResult<PaymentRsp>(null, -26, "提货单据出错");
                }
                if (order.CreateTime.DayOfYear == orderTake.TakeTime.DayOfYear) {
                    if (order.CreateTime.DayOfYear == DateTime.Now.DayOfYear) {
                        if (orderTake.TakeTime <= DateTime.Now) {
                            return new BaseResult<PaymentRsp>(null, -24, "订单状态不是待支付");
                        }
                    }
                } else {
                    if (orderTake.TakeTime.DayOfYear == DateTime.Now.DayOfYear || orderTake.TakeTime.DayOfYear < DateTime.Now.DayOfYear) {
                        return new BaseResult<PaymentRsp>(null, -24, "订单状态不是待支付");
                    }
                }
            }
            var discount = await _order.GetListByOrderBaseId<ICasaMielSession>(order.OrderBaseId).ConfigureAwait(false);

            for (int i = 0; i < discount.Count; i++) {
                if (discount[i].DiscountCouponType == 1) {
                    var a = await _icApiService.Geticticket(new GetTicticketReq { Cardno = discount[i].CardNO, Pagesize = 200, State = 2, Pageindex = 1 }).ConfigureAwait(false);
                    if (a.code == 0) {
                        var list = JsonConvert.DeserializeObject<TicketItemRoot>(a.content);
                        var ticket = list.Tickets.SingleOrDefault(t => t.Ticketid == discount[i].DiscountCouponId);
                        if (ticket != null) {
                            discount[i].DiscountCouponActualMoney = ticket.Je.ToDecimal(0);
                        } else {
                            return new BaseResult<PaymentRsp>(null, -23, "优惠券不可用");

                        }
                    } else {
                        return new BaseResult<PaymentRsp>(null, -23, "优惠券不可用");
                    }
                } else if (discount[i].DiscountCouponType == 1) {

                }
            }



            var p_tradeno = $"C{DateTime.Now.ToString("yyMMddHHmmssfff", CultureInfo.CurrentCulture)}";
            //var reorder = await _storeApiService.GetOrderByOrderCodeAsync(data.OrderCode, mobile);
            // var entity = await _storeService.GetByOrderCodeAsync<ICasaMielSession>(order.OrderCode, mobile);
            var payment = new PaymentRecord {
                OperationMethod =order.Source==11?(int)OperationMethod.Pre: (int)OperationMethod.Waimai,
                TradeNo = p_tradeno,
                Amount = order.PayCashMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                PayMethod = data.PayMethod,
                BillNO = order.OrderCode,
                IcTradeNO = order.IcTradeNO,
                State = 0,
                OperationState = 0,
                CreateTime = DateTime.Now,
                Mobile = mobile
            };
            var shopno = "";
            var shopinfo = await _storeService.GetByStoreIdAsync<ICasaMielSession>(order.StoreId).ConfigureAwait(false);
            payment.ShopName = shopinfo.StoreName;
            payment.ShopId = shopinfo.RelationId;

            var cachekey = string.Format(CultureInfo.CurrentCulture, Constant.SHOPNO, _memcachedPrex, payment.ShopId.Value);
            shopno = await _memcachedClient.GetValueAsync<string>(cachekey).ConfigureAwait(false);
            if (string.IsNullOrEmpty(shopno)) {
                var basedata = await _icApiService.BasedataQuery(new BasedataqueryReq { Datatype = 3, Datavalue = $"{payment.ShopId.Value}" }).ConfigureAwait(false);
                if (basedata.code == 0) {
                    var d = JsonConvert.DeserializeObject<JArray>(basedata.content);
                    if (d.Count > 0) {
                        shopno = d[0]["no"].ToString();
                        await _memcachedClient.AddAsync(cachekey, shopno, 72000).ConfigureAwait(false);
                    }
                }
            }
            payment.ShopNO = shopno;


            if (order.PayCashMoney == 0) {
                var pay = new IcConsumepayReq {
                    Shopid = Storeinfo.RelationId,
                    Tradeno = order.IcTradeNO,
                    Phoneno = mobile
                };
                //pay.Paycontent = new List<IcConsumepayReq.PaycontentItem>();

                pay.Paycontent = new List<IcConsumepayReq.PaycontentItem>
                  {
                        new IcConsumepayReq.PaycontentItem
                        {
                            Paytype = "3",
                            Paymoney = _apiname == "doncoApi"?$"{order.OrderMoney-order.DiscountMoney}".ToDouble(0):order.PayCashMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                            Paytradeno = $"c{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}"
                        }
                    };
                discount.ForEach((Action<Order_DiscountCouponEntity>)(x => {
                    var _paytype = "5";
                    if (x.DiscountCouponType == 1) { _paytype = "6"; }

                    pay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                        Paytype = _paytype,
                        Paymoney = x.DiscountCouponActualMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                        Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                        Payuser = $"{x.DiscountCouponId}"
                    });
                }));
                //if (data.DiscountCouponId > 0) {
                //    pay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                //        Paytype = "6",
                //        Paymoney = data.DiscountCouponMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                //        Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                //        Payuser = $"{data.DiscountCouponId}"
                //    });
                //}


                var zmodel = await _icApiService.Icconsumepay(pay).ConfigureAwait(false);
                if (zmodel.code == 0) {
                    payment.PayMethod = data.PayMethod;
                    payment.PayTime = DateTime.Now;
                    payment.State = 1;
                    payment.OperationState = 1;
                    using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                        order.OrderStatus = (int)OrderStatus.Paid;
                        order.PayTime = DateTime.Now;
                        await _order.OrderBaseUPdateAsync(order, uow).ConfigureAwait(true);
                        await _order.UpdateOrderTakeStatus(order.OrderBaseId, 0, "", uow).ConfigureAwait(true);
                        payment.State = 1;
                        payment.OperationState = 1;
                        payment.PayTime = DateTime.Now;
                        await _paymentService.AddAsync(payment, uow).ConfigureAwait(true);
                        var noticEntity = new NoticeBaseEntity() {
                            RemindTime = DateTime.Now.AddMinutes(-3),
                            CreateTime = DateTime.Now,
                            RelationId = order.OrderBaseId,
                            StoreId = order.StoreId,
                            NoticeType = 0
                        };
                        await _notice.AddAsync(noticEntity, uow).ConfigureAwait(true);

                    }
                    // return new JsonResult(new { code = 0, content = new { paymentrequest = "", ordercode = order.OrderCode, payMethod = payment.PayMethod.ToString(), payed = true } });
                    payRsp.Payed = true;

                    return new BaseResult<PaymentRsp>(payRsp, 0, "");
                }
                return new BaseResult<PaymentRsp>(null, zmodel.code, zmodel.msg);
            }

            switch (data.PayMethod) {
                case 3:
                    if (string.IsNullOrEmpty(data.PayCardNO)) {
                        return new BaseResult<PaymentRsp>(null, 999, "卡号不能为空");
                    }
                    var cardinfo = await _memberCardService.FindAsync<ICasaMielSession>(data.PayCardNO, mobile).ConfigureAwait(false);
                    if (cardinfo == null) {
                        return new BaseResult<PaymentRsp>(null, 999, "卡号有误");
                    }

                    var pay = new IcConsumepayReq {
                        Cardno = data.PayCardNO,
                        Shopid = Storeinfo.RelationId,
                        Tradeno = order.IcTradeNO,
                        Createinvoice = true
                    };
                    pay.Paycontent = new List<IcConsumepayReq.PaycontentItem>
                    {
                        new IcConsumepayReq.PaycontentItem
                        {
                            Paytype = "3",
                            Paymoney = _apiname == "doncoApi"?$"{order.OrderMoney-order.DiscountMoney}".ToDouble(0):order.PayCashMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                            Paytradeno = $"c{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}"
                        }
                    };
                    discount.ForEach((Action<Order_DiscountCouponEntity>)(x => {
                        var _paytype = "5";
                        if (x.DiscountCouponType == 1) { _paytype = "6"; }

                        pay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                            Paytype = _paytype,
                            Paymoney = x.DiscountCouponActualMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                            Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                            Payuser = $"{x.DiscountCouponId}"
                        });
                    }));
                    //if (data.DiscountCouponId > 0) {
                    //    pay.Paycontent.Add(new IcConsumepayReq.PaycontentItem {
                    //        Paytype = "6",
                    //        Paymoney = data.DiscountCouponMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                    //        Paytradeno = $"t{DateTime.Now.ToString("yyMMddHHmmssffff", CultureInfo.CurrentCulture)}",
                    //        Payuser = $"{data.DiscountCouponId}"
                    //    });
                    //}
                    if (order.FreightMoney > 0) {
                        pay.Payfee = new List<IcConsumepayReq.PayfeeItem>{new IcConsumepayReq.PayfeeItem
                        {
                            Fee = order.FreightMoney.ToString(CultureInfo.CurrentCulture).ToDouble(0),
                            Feetype="1",
                            Description = "配送费"
                        }};
                    }
                    var zcard = await _icApiService.GetCardBalance(data.PayCardNO, $"{LoginInfo.Item3}099".ToInt32(0)).ConfigureAwait(false);
                    if (zcard.code == 0) {
                        var Obj = JsonConvert.DeserializeObject<JObject>(zcard.content);
                        var balance = Obj["totalmoney"].ToDecimal(0);
                        if (balance < order.PayCashMoney) {
                            if (cardinfo.CardType == "3")//幸福卡
                            {
                                return new BaseResult<PaymentRsp>(null, -40, "卡内余额不足");

                            }
                            return new BaseResult<PaymentRsp>(null, -39, "卡内余额不足");
                        }
                        //if ((data.payMethod == 3) && (cardinfo.CardType == "3"))
                        //{
                        //    return new BaseResult<PaymentRsp>(null, -41, "优惠券不能与幸福卡同时使用");
                        //}
                    } else {
                        return new BaseResult<PaymentRsp>(null, zcard.code, zcard.msg);
                    }
                    payment.PayMethod = (int)PayMethod.Card;
                    payment.State = 1;
                    payment.OperationState = 1;
                    payment.PayTime = DateTime.Now;
                    var zmodel = await _icApiService.Icconsumepay(pay).ConfigureAwait(false);
                    if (zmodel.code == 0) {
                        var jobject = JsonConvert.DeserializeObject<JObject>(zmodel.content);
                        if (jobject != null && jobject["invoiceqrcode"] != null) {
                            var invoiceUrl = jobject["invoiceqrcode"].ToString();
                            await _order.UpdateOrderInvoiceUrlByOrderCodeAsync<ICasaMielSession>(payment.BillNO, invoiceUrl).ConfigureAwait(false);
                        } else {
                            logger.Error($"Invoideurl:{zmodel.content}");
                        }
                        //var jobject = JsonConvert.DeserializeObject<JObject>(zmodel.content);
                        //var tradeno = jobject["tradeno"].ToString();
                        //payment.OutTradeNo = tradeno;
                        //todo:zhifucg
                        using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                            order.OrderStatus = (int)OrderStatus.Paid;
                            order.PayMethod = payment.PayMethod;
                            order.PayTime = DateTime.Now;
                            await _order.OrderBaseUPdateAsync(order, uow).ConfigureAwait(true);
                            await _order.UpdateOrderTakeStatus(order.OrderBaseId, 0, "", uow).ConfigureAwait(true);
                            await _paymentService.AddAsync(payment, uow).ConfigureAwait(true);

                            var noticEntity = new NoticeBaseEntity() {
                                RemindTime = DateTime.Now.AddMinutes(3),
                                CreateTime = DateTime.Now,
                                RelationId = order.OrderBaseId,
                                StoreId = order.StoreId,
                                NoticeType = 0
                            };
                            await _notice.AddAsync(noticEntity, uow).ConfigureAwait(true);
                        }
                        var logdata = new UserLog { Url = Request.GetShortUri(), OPInfo = $"外卖订单支付,卡号:[{data.PayCardNO}],支付金额{order.PayCashMoney}，订单号：{order.OrderCode}", OPTime = DateTime.Now, UserName = mobile, UserIP = Request.GetUserIp() };
                        await _userLog.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
                        //var cmd = new SendOrderPaySuccessTemplateMessageCommand { OrderCode = order.OrderCode };
                        //await _mediator.Send(cmd);

                        // await _storeApiService.SendOrderNotice(order.OrderCode);
                        //return new JsonResult(new { code = 0, content = new { paymentrequest = "", ordercode = order.OrderCode, payMethod = payment.PayMethod.ToString(), payed = true } });
                        payRsp.Payed = true;
                        var cmd3 = new OrderCreateMemberCouponCommand { ActivityId = 6, OrderCode = order.OrderCode };
                        var rsp = await _mediator.Send(cmd3).ConfigureAwait(false);
                        logger.Trace($"OrderCreateMemberCouponCommand:{order.OrderCode},{JsonConvert.SerializeObject(rsp)}");
						if (order.Source == 11) {
                            var storeentity = await _storeService.GetByStoreIdAsync<ICasaMielSession>(order.StoreId).ConfigureAwait(false);
                            var precommd = new PreOrderPaySucessSubscribeMessageCommand { Mobile = mobile,OrderCode=order.OrderCode };
                            precommd.Data = new string[] { order.TakeCode, storeentity?.StoreName, storeentity?.FullAddress, $"¥{order.PayMoney.ToString("#", CultureInfo.CurrentCulture)}", "已下单" };
                            await _mediator.Send(precommd).ConfigureAwait(false);
                         }



                        return new BaseResult<PaymentRsp>(payRsp, 0, "");
                        //return new JsonResult(new { code = 0, content = entity, payMethod = 3, payed = true });
                    } else {
                        return new BaseResult<PaymentRsp>(null, zmodel.code, zmodel.msg);

                    }
                default:
                    using (var uow = _session.UnitOfWork(IsolationLevel.Serializable)) {
                        order.LastUpdateTime = DateTime.Now;
                        await _order.OrderBaseUPdateAsync(order, uow).ConfigureAwait(true);
                    }
                    var command = new CreatePaymentRequestCommand(payment, data.id, PaymentScenario.Waimai);
                    var result = await _mediator.Send(command).ConfigureAwait(false);
                    logger.Trace($"payment:{JsonConvert.SerializeObject(result)}");
                    payRsp.Paymentrequest = result.Paymentrequest;
                    payRsp.Payed = result.Payed;
                    return new BaseResult<PaymentRsp>(payRsp, 0, "");
            }
        }

        /// <summary>
        /// 取消订单
        /// </summary>
        /// <param name="req"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<ActionResult<BaseResult<string>>> CancelOrder([FromBody]  OrderRefundReq req, [FromHeader(Name = "u-token")]  string token)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }

            var mobile = MemberHelper.GetMobile(token);

            logger.Trace($"{JsonConvert.SerializeObject(req.OrderCode)}");

            var entity = await _order.GetByOrderCodeAsync<ICasaMielSession>(req.OrderCode, mobile).ConfigureAwait(false);
            logger.Trace($"Refund:{JsonConvert.SerializeObject(entity)}");
            if (entity != null) {
                if (entity.OrderStatus == (int)OrderStatus.Paid) {
                    if (entity.PayTime.Value.AddMinutes(4) < DateTime.Now) {
                        return Ok(new { code = 9999, msg = "超出订单取消时间，请联系门店" });
                    }
                    if (entity.ExpressStatus > 1) {
                        return Ok(new { code = 9999, msg = "已发货不能取消订单" });
                    }
                    var cmd = new CancelMemberCouponCommand("", req.OrderCode, 1, 6);
                    var rsp = await _mediator.Send(cmd).ConfigureAwait(false);
                    if (rsp.Code != 0) {
                        return rsp;
                    }

                    var m = await _refundService.OrderRefund(req).ConfigureAwait(false);
                    if (m.code == 0) {
                        var command = new CancelOrderMemberCouponCommand { OrderCode = req.OrderCode };
                        await _mediator.Publish(command).ConfigureAwait(false);
                        await _order.OrderOperationLogAddAsync<ICasaMielSession>(new OrderOperationLog {
                            BillType = 2, CreateTime = DateTime.Now, Remark = "用户发起订单取消成功",
                            OrderBaseId = entity.OrderBaseId, OrderCode = entity.OrderCode
                        }).ConfigureAwait(false);
                    }
                    return Ok(m);
                } else {
                    return Ok(new { code = 9999, msg = "订单状态不是已支付" });
                }
            } else {
                return Ok(new { code = 9999, msg = "订单不存在！" });

            }

        }
        /// <summary>
        /// 我的外卖订单列表(小程序用）
        /// </summary>
        /// <param name="req"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<PagingResultRsp<List<CakeOrderGetListRsp>>> MyOrders([FromBody]GetMyAllOrdersReq req, [FromHeader(Name = "u-token")] string token)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }

            var mobile = MemberHelper.GetMobile(token);
            var cmd = new GetMyOrderListCommand(LoginInfo.Item3) { Mobile = mobile, PageIndex = req.PageIndex, PageSize = req.PageSize, Status = req.Status };
            var result = await _mediator.Send(cmd).ConfigureAwait(false);
            return result;
        }

        /// <summary>
        /// 
        ///获取订单详情
        /// </summary>
        /// <returns>The detail.</returns>
        /// <param name="req">Req.</param>
        /// <param name="token">Token.</param>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<BaseResult<CakeOrderBaseRsp>> GetDetail([FromBody]GetOrderDetailReq req, [FromHeader(Name = "u-token")]string token)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }

            var mobile = MemberHelper.GetMobile(token);
            var cmd = new GetOrderDetailCommand(req.OrderCode, mobile,LoginInfo.Item3);
            var result = await _mediator.Send(cmd).ConfigureAwait(false);
            return result;
        }
    }
}
